/**
 *   DataSlim - Lazy Loading Framework
 *   Copyright (C) 2007 Rodolfo Dias
 *   
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this program; if not, write to the Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 
 */

package net.dataslim.test.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import net.dataslim.test.IPersistEngine;
import net.dataslim.test.entity.EntityDetail;
import net.dataslim.test.entity.EntityMaster;

public class PersistEngineJDBC implements IPersistEngine{

	private String SQL_INSERT_MASTER = "Insert into master values(?,?)";
	private String SQL_INSERT_DETAIL = "Insert into detail values(?,?,?)";
	private String SQL_FIND_ENTITY_MASTER = "Select * from master where id = ?";
	private String SQL_GET_DETAIL = "Select * from detail where master_id = ?";
	private PreparedStatement pstmtInsertDetail;
	private PreparedStatement pstmtInsertMaster;
	
	public Object findEntity(Class c, Long idMaster) throws Exception {
	
		if (c.equals(EntityMaster.class)){
			return findEntityMaster(idMaster);
		}else{
			return getEntityDetails(idMaster);
		}
	}
	
	private EntityMaster findEntityMaster(Long idMaster) throws Exception{
		DBUtils db = new DBUtils();
		Connection conn= null;
		PreparedStatement pstmt= null;
		ResultSet rst = null;
		EntityMaster master = null;
		try{
			conn = db.getConnection();
			pstmt = conn.prepareStatement(SQL_FIND_ENTITY_MASTER);
			pstmt.setLong(1, idMaster.longValue());
			rst = pstmt.executeQuery();
			if (rst.next()){
				master = new EntityMaster();
				master.setId(new Long(rst.getLong("id")));
				master.setDescription(new String("description"));
			}else{
				throw new Exception("Master com Id: "+idMaster+" nao encontrado.");
			}
		}finally{
			db.close(rst);
			db.close(pstmt);
			db.close(conn);
		}
		return master;
	}
	
	
	private List<EntityDetail> getEntityDetails(Long idMaster) throws Exception{
		DBUtils db = new DBUtils();
		Connection conn= null;
		PreparedStatement pstmt= null;
		ResultSet rst = null;
		List<EntityDetail> lstDetail = new ArrayList<EntityDetail>();
		try{
			conn = db.getConnection();
			pstmt = conn.prepareStatement(SQL_GET_DETAIL);
			pstmt.setLong(1, idMaster.longValue());
			rst = pstmt.executeQuery();
			while(rst.next()){
				EntityDetail detail = new EntityDetail();
				detail.setId(new Long(rst.getLong("id")));
				detail.setDescription(new String("description"));
				detail.setIdEntityMaster(new Long(rst.getLong("master_id")));
				lstDetail.add(detail);
			}
		}finally{
			db.close(rst);
			db.close(pstmt);
			db.close(conn);
		}
		return lstDetail;
	}

	public void persist(EntityMaster entityMaster) throws Exception {
		DBUtils db = new DBUtils();
		Connection conn = db.getConnection();
		conn.setAutoCommit(false);
		try{
			persistMaster(entityMaster, conn);
			persistDetail(entityMaster.getEntityDetails(), entityMaster.getId(), conn);
			conn.commit();
		}catch(Exception e){
			conn.rollback();
		}finally{
			db.close(conn);
			db.close(pstmtInsertMaster);
			db.close(pstmtInsertDetail);
		}
	}
	
	private void persistMaster(EntityMaster entityMaster, 
			Connection conn) throws Exception{
			pstmtInsertMaster = conn.prepareStatement(SQL_INSERT_MASTER);
			pstmtInsertMaster.setLong(1, entityMaster.getId());
			pstmtInsertMaster.setString(2, entityMaster.getDescription());
			pstmtInsertMaster.executeUpdate();
	}
	
	private void persistDetail(List<EntityDetail> lstEntityDetail,
			Long idMaster,
			Connection conn) throws Exception{
		pstmtInsertDetail = conn.prepareStatement(SQL_INSERT_DETAIL);
		for(EntityDetail entityDetail:lstEntityDetail){
			pstmtInsertDetail.setLong(1, entityDetail.getId().longValue());
			pstmtInsertDetail.setString(2, entityDetail.getDescription());
			pstmtInsertDetail.setLong(3, idMaster.longValue());
			pstmtInsertDetail.executeUpdate();
		}
	}

}
